#include "mat_sfx.h"
#include "mat_sfx_manager.h"
#include "mat_game.h"

#include "math/facing.h"
#include "part2d/part2d.h"
#include "num/rand.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros




MATSfx::MATSfx(MATSfx::SFX_TYPES Type) : 
								m_Type(Type),
								m_RotationSpeed(0),
								m_bShouldRandomRotate (true),
								m_Alpha(1.0f),
								m_Scale(1.0f),
								m_pParticle(NULL),								
								m_bShouldDisappearWithCounter(false),
								m_Delay(0.0f)  ,
								m_Rotation(0),
								m_SoundSFXName(MATSounds::SFX_NONE),
								m_IsPostRender(false),
								m_SkipDrawing(false),
								m_IsToSpawnOnce(false),
                                m_TriggerCount(1),							
								m_IsTickCreationFinish(false)
{
	
	m_bShouldDisappearWithCounter = true;	
	m_DisappearCounter.SetLimit(0.5f);
	m_SpawnSize = math::Vec2(0.0025f,0.0025f);

	// call last
	MapTypeToName();

	
}

MATSfx::~MATSfx()
{
	Clear();
}


void	MATSfx::Render(const math::Vec2& Offset,float Scale)
{
	if(!m_IsAlive)
		return;

	if(m_Delay > 0)
		return;

	if(m_SkipDrawing)
		return;

	math::Vec2 TempOffset;
	if(m_IsPostRender)
		TempOffset = math::Vec2(0,0);
	else 
		TempOffset = Offset;
	

    Scale = Scale *  (m_Scale );
	if(m_pParticle)
	{
		m_pParticle->Render(-TempOffset ,
                             m_Scale
                             );
		
	}
	else
	{
		m_Sprite.m_Pos = m_Pos + TempOffset + m_RandomMovePos;
		m_Sprite.m_Size = m_Size * Scale;
		m_Sprite.m_Rotation = m_Rotation;
		m_Sprite.m_Color = ColorfRGBA(1.0f,1.0f,1.0f,m_Alpha);
		m_Sprite.RenderRotated();

	}

	
}


void	MATSfx::SetPoition(const math::Vec2& Pos)
{
	m_Pos = Pos;
	if(m_pParticle)
		m_pParticle->SetPos(m_Pos);
}

void	MATSfx::RenderDebug(const math::Vec2& Offset,float Scale)
{
	
}

void	MATSfx::Tick(float dt)
{
	if(!m_IsAlive)
		return;

	if(m_Delay > 0)
	{
		m_Delay -= dt;		
		if(m_Delay <= 0)
		{
			if(m_pParticle)
			{
				m_pParticle->Clear();
				for(int i = 0; i < m_TriggerCount; i++)
					m_pParticle->TickCreation(10.0f, m_Pos - (m_SpawnSize * 0.5f) , m_SpawnSize);
			}
			if(m_SoundSFXName != MATSounds::SFX_NONE)
				MATSounds::Instance().PlaySoundSFX(m_SoundSFXName);	
		}
		
		return;
	}

	if( m_bShouldDisappearWithCounter )
	{
		m_DisappearCounter.Tick(dt);
		if( m_DisappearCounter.IsReady())
		{
			//m_IsAlive = false;
			m_IsTickCreationFinish = true;
			//return;
		}
		
	}
	else
	{
		bool test = true;
	}


	if(m_bShouldRandomRotate)
		m_Rotation += (m_RotationSpeed * dt);
	
	
	if(m_pParticle)
	{	
		m_pParticle->Tick(dt);		

		if(!m_IsToSpawnOnce && !m_IsTickCreationFinish)
		{
			m_pParticle->TickCreation(dt,m_Pos - (m_SpawnSize * 0.5f), m_SpawnSize);
		}
		
		if(m_IsTickCreationFinish)
		{
			m_IsAlive = m_pParticle->IsActive();
			if(!m_IsAlive)
				bool Test = true;
		}
			
	}
	else
	{
		m_RandomMovePos += (m_RandomDir * dt);
		m_Alpha -= dt;		

		if(!m_Sprite.Tick(dt))
			m_IsAlive = false;
		
	}

	
}


void	MATSfx::Clear()
{
	UTIL_SAFE_DELETE(m_pParticle);	
}


void		MATSfx::Load(const std::string& Name)
{
  	m_Sprite.Create(Name);
	m_Size = m_Sprite.m_Size;
}

void		MATSfx::ParticleLoad(const std::string& Name, int TriggerCount)
{
	MATSfx* pCacheSfx = MATSFXManager::Instance().GetCacheSfx(m_Type);
    m_TriggerCount = TriggerCount;
	if(pCacheSfx)
	{
		m_pParticle = pCacheSfx->m_pParticle->Clone();		
		return;
	}          	 

	m_pParticle = new part2d::Part2D();
	m_pParticle->Load(Name);
	
	
	
}

MATSfx*		MATSfx::ReSpawn(const math::Vec2& Pos, 
									  float ScaleSize,
									  float Rotation,
									  MATSounds::SOUND_NAMES SFXName,
									  bool	bIsRegen
									 
									  )
{
	m_IsPostRender = false;
	m_SkipDrawing = false;
	m_SoundSFXName = SFXName;
	if(m_SoundSFXName != MATSounds::SFX_NONE)
		MATSounds::Instance().PlaySoundSFX(m_SoundSFXName);	

	m_Scale = ScaleSize;
	m_Pos = Pos;
	m_Rotation = Rotation;
	m_RandomMovePos = math::Vec2(0,0);
			
	if(m_pParticle)
	{
		// make it finish
		m_pParticle->Clear();
		
	}


	m_IsAlive = true;

	if(!bIsRegen && m_bShouldDisappearWithCounter)
		m_DisappearCounter.Reset();


	for(int i = 0; i < m_TriggerCount; i++)
	{
       if(m_pParticle)
           m_pParticle->TickCreation(10.0f, m_Pos - (m_SpawnSize * 0.5f) , m_SpawnSize);
	}
	m_IsTickCreationFinish = false;

	return this;
}

void		MATSfx::MapTypeToName()
{

	switch(m_Type)
	{
		case SFX_NONE:
		break;

		case SFX_SELECTED:
			ParticleLoad("effects/potion_ingredient.p2d" , 1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 60.0f;
			m_SpawnSize = MATGame::GetGemSize() * 0.4f;
			break;

		case SFX_MATCH:
			ParticleLoad("effects/match_celestial_winfx.p2d", 1);			
		break;

		case SFX_BOMBMATCH:
			ParticleLoad("effects/bombmatch_celestial_winfx.p2d", 1);			
			break;

		case SFX_MOVE:
			ParticleLoad("effects/move_fairy_repulse.p2d", 1);			
		break;	

		case SFX_TROPHY_ANIMATE:
			ParticleLoad("effects/trophyanimate_cursor_sparkle.p2d", 1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 1.0f;
		
			break;
		case SFX_MOVETOTARGET:
			ParticleLoad("effects/movetarget_lightning_boom.p2d", 1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 0.5f;			
			break;
		case SFX_TREASURECHEST_SPARKLE:
			ParticleLoad("effects/sparkles.p2d", 1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 1000.0f;			
			break;
		case SFX_RATINGSTAR_APPEAR:
			ParticleLoad("effects/ratedstar_appear_fx_stars_inwards04.p2d" , 1);		
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 1.0f;			
			break;

		case SFX_TILE_EXPLODE:
			ParticleLoad("effects/tileexplode_draw017a_draw.p2d", 22);	
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 2.09f;	
			m_IsToSpawnOnce = true;
			m_SpawnSize = MATGame::GetGemSize() * 0.9f;
			
			break;
		case SFX_TILEUNMOVEABLE_EXPLODE:
			ParticleLoad("effects/tileexplode2_draw017a_draw.p2d", 4);	
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 2.09f;	
			m_IsToSpawnOnce = true;
			m_SpawnSize = MATGame::GetGemSize() * 0.4f;
			break;
	
		case SFX_UNREACHABLE_EXPLODE:
			ParticleLoad("effects/tileexplode3_draw017a_draw.p2d", 15);	
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 2.09f;	
			m_IsToSpawnOnce = true;
			m_SpawnSize = MATGame::GetGemSize() * 0.4f;
			break;

		case SFX_GOT_3STARS:
			ParticleLoad("effects/sfx_fireworks.p2d" , 1);		
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 1.5f;		
			m_SpawnSize = math::Vec2( 0.075f,0.075f);
			break;

		case SFX_BOMB_EXPLODE:
			ParticleLoad("effects/bomb_explode_power4.p2d" , 1);		
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 1.0f;		
			m_SpawnSize = MATGame::GetGemSize() * 0.4f;
			break;

		case SFX_BONUS_TIME:
			ParticleLoad("effects/Bonus_time.p2d" , 1);					
			break;

		default:
			break;

	}
}


void	MATSfx::FollowMe(const math::Vec2& Pos)
{
	m_Pos = Pos;
	if(m_pParticle)
		m_pParticle->SetPos(Pos / ((float)GraphicsUtil::WIDTH / (float)TEXTURE_WIDTH) );
}

void	MATSfx::ToDie()
{
	 m_IsAlive = false;
	 if(m_pParticle)
		 m_pParticle->Tick(1000.0f);	// make it finish

}